package cn.barudisshu.handler.route;

import cn.barudisshu.handler.Handler;
import cn.barudisshu.http.HttpMethod;
import cn.barudisshu.http.WebException;
import cn.barudisshu.http.servlet.HttpRequest;
import cn.barudisshu.http.servlet.HttpResponse;
import cn.barudisshu.matcher.RestRequestMatch;
import cn.barudisshu.route.Route;
import cn.barudisshu.route.RouteBuilder;
import cn.barudisshu.route.RouteInvocation;
import com.google.common.base.Optional;

import java.util.Map;
import java.util.Set;

/**
 * @author galudisu
 */
public class RouteHandler extends Handler {

    private final RouteBuilder routeBuilder;

    public RouteHandler(RouteBuilder routeBuilder) {
        this.routeBuilder = routeBuilder;
    }

    @Override
    public void handle(HttpRequest request, HttpResponse response, boolean isHandled) {

        //请求 rest路径
        String restPath = request.getRestPath();
        Map<String, Map<String, Set<Route>>> routesMap = routeBuilder.getRoutesMap();
        Set<Route> routesSet;
        Optional<? extends RestRequestMatch> requestMatch = null;
        Route route = null;
        RouteInvocation routeInvocation = null;

        String httpMethod = request.getHttpMethod();
        boolean supportMethod = HttpMethod.support(httpMethod);

        if(supportMethod){
            if (routesMap.containsKey(httpMethod)){
                Set<Map.Entry<String, Set<Route>>> routesEntrySet = routesMap.get(httpMethod).entrySet();
                //url区分
                for (Map.Entry<String, Set<Route>> routesEntry : routesEntrySet) {
                    if (restPath.startsWith(routesEntry.getKey())) {
                        routesSet = routesEntry.getValue();
                        for (Route r : routesSet) {
                            requestMatch = r.match(request, response);
                            if (requestMatch != null) {
                                route = r;
                                break;
                            }
                        }
                        if (requestMatch != null) {
                            break;
                        }
                    }
                }

            }
        }

        if(requestMatch != null){
            // todo: 根据路由 route 和 requestMatch ，渲染视图资源
            routeInvocation = new RouteInvocation(route,requestMatch, request,response);


        }
        isHandled = true;
        //route
        if (routeInvocation != null) {
            routeInvocation.invoke();
        } else {
            if (!restPath.equals("/") && supportMethod) {
                // no route matched
                // TODO: 2017/1/19 throw API unavailable exception
                throw new WebException("API is unavailable,check request body.");
            } else {
                isHandled = false;
            }
        }
    }
}
